﻿/************************************************************************
 * SMLib - State Model Library
 * Copyright (C) 2012-2013 Ali Khalili (khalili_DOT_ir_@SIGN_gmail_DOT_com)
 * **********************************************************************
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License (LGPL) published 
 * by the Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version. This program is distributed without any
 * warranty. See the GNU Lesser General Public License for more details. 
 * ***********************************************************************
 * File         :     SMLib\Automata\MM\MM_Constructor.cs
 * Description  :     Constructor of Mealy machine
 * Change log   :     -May 2013:  Initial version
 * To Do        :     
 ************************************************************************/
using System;
using SMLib.Automata.Base;

namespace SMLib.Automata.MM
{
    /// <summary>
    /// Construct a Mealy Machine
    /// </summary>
    public class MM_Constructor
    {
        MealyMachine myMM;
        Alphabet Sigma;
        //bool deterinistic;

        /// <summary>
        /// Constructor
        /// <param name="deterinistic">whether the machine is determinustic or not</param>
        /// </summary>
        public MM_Constructor(/*bool deterinistic = true*/)
        {
            //this.deterinistic = deterinistic;
            Sigma = new Base.Alphabet();
            myMM = new MealyMachine(Sigma);
        }

        /// <summary>
        /// Add a transition to Mealy Machine
        /// </summary>
        /// <param name="src">id of source state</param>
        /// <param name="dst">id of destination state</param>
        /// <param name="edge">label of edge</param>
        public void AddEdge(string src, string dst, string input, string output)
        {
            StringSymbol currEdge = new StringSymbol(input);
            if (Sigma.Contains(currEdge))
                Sigma.AddSymbol(currEdge);
            MealyMachine.Mealy_State srcSt = null, dstSt = null;
            foreach (MealyMachine.Mealy_State st in myMM.GetAllStates())
            {
                if (st.Identifier.Equals(src))
                    srcSt = st;
                if (st.Identifier.Equals(src))
                    dstSt = st;
                if (dstSt != null && srcSt != null)
                    break;
            }
            if (dstSt == null)
            {
                dstSt = new MealyMachine.Mealy_State(dst);
            }
            if (srcSt == null)
            {
                srcSt = new MealyMachine.Mealy_State(src);
            }
            srcSt.Transitions.Add(new MealyMachine.Mealy_Transition(currEdge, new StringSymbol(output)));
        }


        /// <summary>
        /// Generate the Mealy Machine
        /// </summary>
        /// <returns>the generated Mealy Machine</returns>
        public MealyMachine Generate()
        {
            return myMM;
        }
    }
}
